import { _decorator, AudioSource, Component, easing, Input, input, instantiate, Label, Layout, math, Node, Prefab, tween, UIOpacity, Vec3 } from 'cc';
import { CardData } from './CardData';
import { Card } from './Card';
import { CardEnum } from './CardEnum';
import { HeartController } from './HeartController';
import { CardResult } from './CardResult';
const { ccclass, property } = _decorator;

@ccclass('GameUI')
export class GameUI extends Component {
    @property(AudioSource)
    public LostAudio: AudioSource;
    @property(AudioSource)
    public WinAudio: AudioSource;

    @property(AudioSource)
    public ClickAudio: AudioSource;

    @property(Node)
    public left_known_Card: Node;

    @property(Node)
    public right_known_card: Node;


    @property(Node)
    public left_boom: Node;

    @property(Node)
    public right_boom: Node;

    @property(Node)
    public vs: Node;

    @property(Layout)
    public LayoutUI: Layout;
    @property(Prefab)
    public CardPrefab: Prefab;


    @property(HeartController)
    public playerController: HeartController;
    @property(HeartController)
    public aiController: HeartController;



    @property(Node)
    public You_Win: Node;
    @property(Node)
    public You_Lost: Node;
    @property(Label)
    public total_win: Label;
    @property(Node)
    public choose_your_card: Node;

    public playerCards: CardData[] = [];// 玩家卡牌
    public aiCards: CardData[] = [];//ai卡牌

    public total_win_num = 0;//总共赢了多少人

    // 双方血量
    public playerheart = 3;
    public aiheart = 3;

    private boomHurtVal = 3;
    private shootHurtVal = 1

    protected onLoad(): void {
    }


    start() {
        this.gameStart();
    }

    update(deltaTime: number) {

    }



    public disposePlayerCardsDisplay() {
        this.LayoutUI.node.removeAllChildren();
    }

    private playerCardSort(l: CardData, r: CardData) {
        return r.cardValue - l.cardValue;
    }

    public upPlayerCard() {
        this.disposePlayerCardsDisplay();
        this.playerCards.sort(this.playerCardSort.bind(this));
        let c = this.playerCards;
        let idx = 0;
        for (let i in c) {
            let s = instantiate(this.CardPrefab);
            this.LayoutUI.node.addChild(s);
            let comp = s.getComponent(Card);
            comp.node.setScale(Vec3.ONE);


            comp.setData(c[i],this.onCardClickHandler,this);

            comp.node.on(Input.EventType.MOUSE_UP, this.onCardClickHandler, this);

            ++idx;
        }

    }
    //初始手牌
    private initCardHand() {
        let a = new CardData();
        a.cardValue = CardEnum.reload;

        let b = new CardData();
        b.cardValue = CardEnum.shield;

        return [a, b];
    }

    private getTotalWinString() {
        return "Total Win : " + this.total_win_num;
    }

    private gameStart() {
        this.playerCards = this.initCardHand();
        this.aiCards = this.initCardHand();
        this.You_Win.active = false;
        this.You_Lost.active = false;
        this.left_boom.active = false;
        this.right_boom.active = false;
        tween(this.left_known_Card).stop();
        tween(this.right_known_card).stop();
        this.left_known_Card.active = true;
        this.left_known_Card.setScale(Vec3.ONE)
        this.right_known_card.setScale(Vec3.ONE)
        this.right_known_card.active = true;
        this.choose_your_card.active = true;
        this.total_win.string = this.getTotalWinString();
        this.playerheart = 3;
        this.aiheart = 3;
        this.playerController.setData(this.playerheart);
        this.aiController.setData(this.aiheart);


        tween(this.vs).stop();
        this.vs.setScale(new Vec3(2, 2, 2));
        let p = this.vs.getComponent(UIOpacity);
        p.opacity = 0;
        tween(this.vs).to(0.2, { scale: Vec3.ONE }).delay(0.2).to(0.2, { scale: Vec3.ZERO }).start();
        tween(p).to(0.2, { opacity: 255 }).delay(0.2).to(0.2, { opacity: 0 }).start();

        this.upPlayerCard();


    }

    // 卡牌点击
    public onCardClickHandler(e) {
        this.ClickAudio.play();
        let node = e.currentTarget;
        let card: Card = node.getComponent(Card);

        let cardData: CardData = card.cardData;
        console.log("点击了", cardData);


        let c = this.LayoutUI.node.children;
        this.choose_your_card.active = false;

        let idx = 0;
        for (let i in c) {
            tween(c[i]).stop();
            tween(c[i]).to(0.2, { scale: Vec3.ZERO }).start();

            ++idx;
        }
        // 玩家行为
        this.playerLogic(cardData.cardValue);
        let player_action = cardData.cardValue;
        // ai生成一个行为
        let ai_action = this.aiLogic();



        this.spawnBulletAnim(player_action, ai_action);
        // 
        // this.playAnim(player_action,ai_action);




    }
    private spawnBulletAnim(player_action: number, ai_action: number) {

        let left_card_node = this.left_boom;
        let left_card = left_card_node.getComponent(Card);
        let left_card_data_tmp = new CardData();
        left_card_data_tmp.cardValue = player_action;
        left_card.upCardData(left_card_data_tmp);

        let right_card_node = this.right_boom;
        let right_card = right_card_node.getComponent(Card);
        let right_card_data_tmp = new CardData();
        right_card_data_tmp.cardValue = ai_action;
        right_card.upCardData(right_card_data_tmp);


        this.left_known_Card.setScale(Vec3.ONE);
        tween(this.left_known_Card).stop();
        tween(this.left_known_Card).to(0.2, { scale: new Vec3(0, 1, 0) }).start();

        this.right_known_card.setScale(Vec3.ONE);
        tween(this.right_known_card).stop();
        tween(this.right_known_card).to(0.2, { scale: new Vec3(0, 1, 0) }).start();

        this.left_boom.active = true;
        this.right_boom.active = true;

        this.left_boom.setScale(new Vec3(0, 1, 0));
        tween(this.left_boom).stop();
        tween(this.left_boom).delay(0.2).to(0.2, { scale: Vec3.ONE }).start();


        this.right_boom.setScale(new Vec3(0, 1, 0));
        tween(this.right_boom).stop();
        tween(this.right_boom).delay(0.2).to(0.2, { scale: Vec3.ONE }).start();



        tween(this.node).stop();
        tween(this.node).delay(0.4).call(() => {
            //
            this.tellWhoWin(player_action, ai_action);
        }).start();
    }

    // 告诉玩家谁赢了
    private tellWhoWin(player_action: number, ai_action: number) {
        // 结果
        let result = this.action2Result(player_action, ai_action);
        if (result == CardResult.continue) {
            this.continue(player_action, ai_action);
            this.WinAudio.play();
        }
        else if (result == CardResult.player_win) {
            this.WinAudio.play();
            this.playerWin(player_action, ai_action);
            if (this.playerheart > 0) {
                if (this.aiheart > 0) {
                    this.continue(player_action, ai_action);
                }
                else {
                    this.winAi();
                }
            }
            else
            {
                this.lostAi();
            }
        }
        else if (result == CardResult.player_lost) {
            this.LostAudio.play();
            this.playerLost(player_action, ai_action);
            if (this.playerheart <= 0) {
                this.lostAi();
            }
            else
            {
                this.continue(player_action, ai_action);
            }
        }
        else if (result == CardResult.each_hurt) {
            this.LostAudio.play();
            this.playerLost(player_action, ai_action);
            this.playerWin(player_action, ai_action);
            if (this.playerheart > 0) {
                if (this.aiheart > 0) {
                    this.continue(player_action, ai_action);
                }
                else {
                    this.winAi();
                }
            }
            else
            {
                this.lostAi();
            }
        }
    }

    // 赢了ai
    private winAi() {
        this.total_win_num += 1;
        this.gameStart();
    }

    private lostAi()
    {
        if(this.total_win_num > 0)
        {
            this.total_win_num -= 1;
        }
        this.gameStart();
    }


    // 玩家赢
    private playerWin(player_action: number, ai_action: number) {
        let bofore = this.aiheart;
        if (player_action == CardEnum.boom) {
            this.aiheart -= this.boomHurtVal;
        }
        else if (player_action == CardEnum.shoot) {
            this.aiheart -= this.shootHurtVal;
        }
        if (this.aiheart > 0) {
            this.aiController.hurt(this.aiheart, bofore);
        }
    }
    // 玩家输
    private playerLost(player_action: number, ai_action: number) {
        let bofore = this.playerheart;
        if (ai_action == CardEnum.boom) {
            this.playerheart -= this.boomHurtVal;
        }
        else if (ai_action == CardEnum.shoot) {
            this.playerheart -= this.shootHurtVal;
        }
        if (this.playerheart > 0) {
            this.playerController.hurt(this.playerheart, bofore);
        }
    }

    private continue(player_action: number, ai_action: number) {

        tween(this.left_known_Card).stop();
        this.left_known_Card.setScale(new Vec3(0, 1, 0));
        tween(this.left_known_Card).delay(0.2).to(0.2, { scale: Vec3.ONE }).start();

        tween(this.right_known_card).stop();
        this.right_known_card.setScale(new Vec3(0, 1, 0));
        tween(this.right_known_card).delay(0.2).to(0.2, { scale: Vec3.ONE }).start();

        tween(this.left_boom).stop();
        this.left_boom.setScale(Vec3.ONE);
        tween(this.left_boom).delay(0.2).to(0.2, { scale: new Vec3(0, 1, 0) }).start();


        tween(this.right_boom).stop();
        this.right_boom.setScale(Vec3.ONE);
        tween(this.right_boom).delay(0.2).to(0.2, { scale: new Vec3(0, 1, 0) }).start();



        tween(this.node).stop();
        tween(this.node).delay(0.4).call(() => {
            this.continueGame();
            //
            this.left_boom.active = false;
            this.right_boom.active = false;

        }).start();
    }
    // 移除牌组前的所有炸弹
    private removeBoom() {
        while (this.hadBootm(this.playerCards)) {
            let idx = this.playerCards.findIndex(p => p.cardValue == CardEnum.boom);
            this.playerCards.splice(idx, 1);
        }
        while (this.hadBootm(this.aiCards)) {
            let idx = this.aiCards.findIndex(p => p.cardValue == CardEnum.boom);
            this.aiCards.splice(idx, 1);
        }
    }

    private hadBootm(cards: CardData[]) {
        return cards.findIndex(p => p.cardValue == CardEnum.boom) != -1
    }
    private hadShoot(cards: CardData[]) {
        return cards.findIndex(p => p.cardValue == CardEnum.shoot) != -1
    }
    // 正常插入炸弹g
    private insertBoom()
    {
        let o = this.playerCards.filter(p=>p.cardValue == CardEnum.shoot);
        let maxBoom = Math.floor( o.length / 3 ); 
        for(let i = 0 ; i < maxBoom ; i++)
        {
            let c = new CardData();
            c.cardValue = CardEnum.boom;
            this.playerCards.push(c);
        }

        
        o = this.aiCards.filter(p=>p.cardValue == CardEnum.shoot);
        maxBoom = Math.floor( o.length / 3 ); 
        for(let i = 0 ; i < maxBoom ; i++)
        {
            let c = new CardData();
            c.cardValue = CardEnum.boom;
            this.aiCards.push(c);
        }

        
    }


    private playerLogic(v: number) {
        this.removeBoom();
        if (v == CardEnum.reload) {
            let c = new CardData();
            c.cardValue = CardEnum.shoot;
            this.playerCards.push(c);
        }
        else if (v == CardEnum.shoot) {
            let idx = this.playerCards.findIndex(p => p.cardValue == CardEnum.shoot);
            if (idx != -1) {
                this.playerCards.splice(idx, 1);
            }
        }
        this.insertBoom();
    }



    // 行为结果
    // 返回玩家交互结果
    private action2Result(player_action: number, ai_action: number) {
        if (player_action == CardEnum.boom) {
            if (ai_action == CardEnum.boom) {
                return CardResult.each_hurt;
            }
            else if (ai_action == CardEnum.shoot) {
                return CardResult.continue;
            }
            else {
                return CardResult.player_win;
            }
        }
        else if (player_action == CardEnum.shoot) {
            if (ai_action == CardEnum.boom) {
                return CardResult.continue;
            }
            else if (ai_action == CardEnum.shoot) {
                return CardResult.each_hurt;
            }
            else if (ai_action == CardEnum.shield) {
                return CardResult.continue;
            }
            else {
                return CardResult.player_win;
            }
        }
        else if (player_action == CardEnum.reload) {
            if (ai_action == CardEnum.boom) {
                return CardResult.player_lost
            }
            else if (ai_action == CardEnum.shoot) {
                return CardResult.player_lost
            }
            else if (ai_action == CardEnum.shield) {
                return CardResult.continue;
            }
            else if (ai_action == CardEnum.reload) {
                return CardResult.continue;
            }
        }
        else if (player_action == CardEnum.shield) {
            if (ai_action == CardEnum.boom) {
                return CardResult.player_lost
            }
            else if (ai_action == CardEnum.shoot) {
                return CardResult.continue;
            }
            else if (ai_action == CardEnum.shield) {
                return CardResult.continue;
            }
            else if (ai_action == CardEnum.reload) {
                return CardResult.continue;
            }
        }

    }
    private continueGame() {
        this.upPlayerCard();
        this.choose_your_card.active = true;
    }


    private aiLogic() {
        if( this.hadBootm(this.aiCards) )
        {
            this.aiBoom();
            return CardEnum.boom;
        }
        else if( this.hadShoot(this.aiCards) )
        {
            this.aiShoot();
            return CardEnum.shoot;
        }
        if( !this.hadShoot(this.playerCards) )
        {
            // 暂时先写死ai一直上膛
            this.aiRealod();
            return CardEnum.reload;
        }
        else 
        {
            let m = Math.random();
            if(m < 0.5)
            {
                // 暂时先写死ai一直上膛
                this.aiRealod();
                return CardEnum.reload;
            }
            else
            {
                return CardEnum.shield;
            }
        }
    }

    private aiShoot()
    {
        let idx = this.aiCards.findIndex(p=>p.cardValue == CardEnum.shoot);
        this.aiCards.splice(idx,1);
    }

    private aiBoom()
    {
        for( let i = 0 ; i < 3 ; i++ )
        {
            let idx = this.aiCards.findIndex(p=>p.cardValue == CardEnum.shoot);
            this.aiCards.splice(idx,1);
        }
    }

    private aiRealod() 
    {
        let s = new CardData();
        s.cardValue = CardEnum.shoot;
        this.aiCards.push(s);
    }

}

